package net.apexcns.core.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;

public class FileUtil {
	@SuppressWarnings("unused")
	private static final Logger logger = Logger.getLogger(FileUtil.class);

	public static final String LS = System.getProperty("line.separator");
	public static final String FS = System.getProperty("file.separator");
	
	//static String rootDir = File.listRoots()[0].toString();
	static String rootDir = System.getProperty("java.io.tmpdir");
	static int rootDirLen = rootDir.length();

	
	public static void main(String[] args) {
		testNormalizeUrlPath();
	}
	
	
	private static void testNormalizeUrlPath() {
		String[] strs = new String[]{".", ".."
				, "//", "//user", "//a///bc"
				, "//a/.", "/a/b/..", "./..", "a"
				, "/test/../test/file"
				, "test/../test/file"
				, ".././test/../test/file"
				, "../d1/./d2/../f1"
				, "a/b/c/../d/../e"
				, "한글은/.///"
				, "특수문자는?"
				, "멍미:\\temp"
				, "C:\\System Volume Information"
				, "", null
		};
		for(String str : strs) {
			System.out.println(str + "\t" + normalizeUrlPath(str,'/'));
		}
	}

	public static String readTextFile(File file, String encoding) throws IOException {
		InputStream in = null;
		try {
			in = new FileInputStream(file);
			return IOUtils.toString(in, encoding);
		} finally {
			IOUtils.closeQuietly(in);
		}
	}

	public static String readTextFile(String filename, String encoding) throws IOException {
		return readTextFile(new File(filename), encoding);
	}

	public static void writeTextFile(File file, String data, String encoding) throws IOException {
		FileUtils.writeStringToFile(file, data, encoding);
	}

	public static void writeTextFile(String filename, String data, String encoding) throws IOException {
		writeTextFile(new File(filename), data, encoding);
	}
	
	public static void close(InputStream is) {
		IOUtils.closeQuietly(is);
	}

	public static void close(OutputStream os) {
		IOUtils.closeQuietly(os);
	}

	public static void skipFully(InputStream in, long len) throws IOException {
		while (len > 0) {
			long ret = in.skip(len);
			if (ret < 0) {
				throw new IOException("Premeture EOF from inputStream");
			}
			len -= ret;
		}
	}
	
	
	public static void copyBytes(InputStream is, OutputStream os) throws IOException {
		copyBytes(is, os, 0L);
	}

	public static void copyBytes(InputStream is, OutputStream os
			, long lengthEd) throws IOException {
		int buffSize = 1024*4;
		byte buf[] = new byte[buffSize];
		try {
			long totalWrite = 0;
			int bytesRead = is.read(buf);
			while (bytesRead >= 0) {
				if(lengthEd>0) {
					long byteLeft = lengthEd - totalWrite;
					if(bytesRead >= byteLeft) {
						os.write(buf, 0, (int)(byteLeft));
//						os.flush();
						return;
					}
					totalWrite += bytesRead;
				}
				os.write(buf, 0, bytesRead);
				bytesRead = is.read(buf);
			}
//			os.flush();
		} finally {
		}
	}
	
	public static void copyBytes(InputStream is, OutputStream os
			, long lengthSt, long lengthEd) throws IOException {
		if(lengthSt>0) skipFully(is, lengthSt);
		copyBytes(is, os, lengthEd);
	}
	
	// need more test
	public static String normalizePath(String filename) {
		return FilenameUtils.normalize(filename);
	}


	public static String normalizeUrlPath(String path) {
		return normalizeUrlPath(path, File.separatorChar);
	}

	public static String normalizeUrlPath(String path, char pathChar) {
		String ret = null;
		try {
			String tmpStr = new File(rootDir+path).getCanonicalPath();
			if(tmpStr.length()<=rootDirLen) {
				ret = pathChar+"";
			} else {
				ret = pathChar + tmpStr.substring(rootDirLen, tmpStr.length());
			}
			if(File.separatorChar != pathChar)
				ret = ret.replace(File.separatorChar, pathChar);
		} catch (IOException e) {
			System.out.print(e.getMessage());
			return null;
		}
		return normalize(ret, true);
	}
	
	// http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/util/RequestUtil.java?view=markup
	public static String normalize(String path, boolean replaceBackSlash) {
			if (path == null) return null;

			// Create a place for the normalized path
			String normalized = path;

			if (replaceBackSlash && normalized.indexOf('\\') >= 0)
				normalized = normalized.replace('\\', '/');

			if (normalized.equals("/.")) return "/";

			// Add a leading "/" if necessary
			if (!normalized.startsWith("/"))
				normalized = "/" + normalized;

			// Resolve occurrences of "//" in the normalized path
			while (true) {
				int index = normalized.indexOf("//");
				if (index < 0)
					break;
				normalized = normalized.substring(0, index)
						+ normalized.substring(index + 1);
			}

			// Resolve occurrences of "/./" in the normalized path
			while (true) {
				int index = normalized.indexOf("/./");
				if (index < 0)
					break;
				normalized = normalized.substring(0, index)
						+ normalized.substring(index + 2);
			}

			// Resolve occurrences of "/../" in the normalized path
			while (true) {
				int index = normalized.indexOf("/../");
				if (index < 0)
					break;
				if (index == 0)
					return (null); // Trying to go outside our context
				int index2 = normalized.lastIndexOf('/', index - 1);
				normalized = normalized.substring(0, index2)
						+ normalized.substring(index + 3);
			}

			// Return the normalized path that we have completed
			return (normalized);

		}
}
